package com.ipnc.dss.util;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;

import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.core.future.IoFutureListener;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.filter.executor.ExecutorFilter;
import org.apache.mina.filter.logging.LoggingFilter;
import org.apache.mina.transport.socket.DatagramSessionConfig;
import org.apache.mina.transport.socket.SocketConnector;
import org.apache.mina.transport.socket.nio.NioDatagramAcceptor;
import org.apache.mina.transport.socket.nio.NioDatagramConnector;
import org.apache.mina.transport.socket.nio.NioSocketConnector;

import com.ipnc.dss.alive.IIPNCKeepAliveFilter;
import com.ipnc.dss.config.Config;

public class IPNCHelper {
	public IPNCHelper() {
	}

	private IoSession ioSession;

	public IoSession instanceTcpCSession(IoHandlerAdapter ioHandler,
			String tcpServer, int tcpPort) {
		SocketConnector tcpConnectorServer = new NioSocketConnector();
		tcpConnectorServer.getFilterChain().addLast("exceutor",
				new ExecutorFilter());
		tcpConnectorServer.setHandler(ioHandler);
		SocketAddress address = new InetSocketAddress(tcpServer, tcpPort);
		ConnectFuture connectFuture = tcpConnectorServer.connect(address);
		connectFuture.awaitUninterruptibly(Config.CONNECT_TIMEOUT);
		connectFuture.addListener(new IoFutureListener<ConnectFuture>() {
			public void operationComplete(ConnectFuture future) {
				if (future.isConnected()) {
					ioSession = future.getSession();
				}
			}
		});
		return ioSession;
	}
	
	public IoSession instanceTcpJSession(IoHandlerAdapter ioHandler,
			String tcpServer, int tcpPort) {
		SocketConnector tcpConnectorServer = new NioSocketConnector();
		tcpConnectorServer.getFilterChain().addLast("exceutor",
				new ExecutorFilter());
		tcpConnectorServer.getFilterChain().addLast("codec",
				new ProtocolCodecFilter(new TextLineCodecFactory()));
		tcpConnectorServer.getFilterChain().addLast("logger",
				new LoggingFilter());

		tcpConnectorServer.setHandler(ioHandler);
		SocketAddress address = new InetSocketAddress(tcpServer, tcpPort);
		ConnectFuture connectFuture = tcpConnectorServer.connect(address);
		connectFuture.awaitUninterruptibly(Config.CONNECT_TIMEOUT);
		connectFuture.addListener(new IoFutureListener<ConnectFuture>() {
			public void operationComplete(ConnectFuture future) {
				if (future.isConnected()) {
					ioSession = future.getSession();
				}
			}
		});
		return ioSession;
	}

	public IoSession instanceUdpJSession(IoHandlerAdapter ioHandler,
			String udpServer, int udpPort, boolean keepAlive) {
		NioDatagramConnector udpConnectorServer = new NioDatagramConnector();
		udpConnectorServer.getFilterChain().addLast("exceutor",
				new ExecutorFilter());
		udpConnectorServer.getFilterChain().addLast("codec",
				new ProtocolCodecFilter(new TextLineCodecFactory()));
		udpConnectorServer.getFilterChain().addLast("logger",
				new LoggingFilter());

		if (keepAlive) {
			udpConnectorServer.getFilterChain().addLast("keep-alive",
					new IIPNCKeepAliveFilter());
		}
		udpConnectorServer.setHandler(ioHandler);
		SocketAddress address = new InetSocketAddress(udpServer, udpPort);
		ConnectFuture connectFuture = udpConnectorServer.connect(address);
		connectFuture.awaitUninterruptibly(Config.CONNECT_TIMEOUT);
		connectFuture.addListener(new IoFutureListener<ConnectFuture>() {
			public void operationComplete(ConnectFuture future) {
				if (future.isConnected()) {
					ioSession = future.getSession();
				}
			}
		});
		return ioSession;
	}
	
	public IoSession instanceUdpCSession(IoHandlerAdapter ioHandler,
			String udpServer, int udpPort, boolean keepAlive) {
		NioDatagramConnector udpConnectorServer = new NioDatagramConnector();
		udpConnectorServer.getFilterChain().addLast("exceutor",
				new ExecutorFilter());
		if (keepAlive) {
			udpConnectorServer.getFilterChain().addLast("keep-alive",
					new IIPNCKeepAliveFilter());
		}
		udpConnectorServer.setHandler(ioHandler);
		SocketAddress address = new InetSocketAddress(udpServer, udpPort);
		ConnectFuture connectFuture = udpConnectorServer.connect(address);
		connectFuture.awaitUninterruptibly(Config.CONNECT_TIMEOUT);
		connectFuture.addListener(new IoFutureListener<ConnectFuture>() {
			public void operationComplete(ConnectFuture future) {
				if (future.isConnected()) {
					ioSession = future.getSession();
				}
			}
		});
		return ioSession;
	}

	public void startIpcameUdpCListener(IoHandlerAdapter ioHandler, int udpPort) {
		NioDatagramAcceptor acceptor = new NioDatagramAcceptor();
		acceptor.setHandler(ioHandler);
		acceptor.getFilterChain().addLast("exceutor", new ExecutorFilter());
		acceptor.getFilterChain().addLast("logger", new LoggingFilter());
		acceptor.getFilterChain().addLast("keep-alive",
				new IIPNCKeepAliveFilter());
		DatagramSessionConfig dcfg = acceptor.getSessionConfig();
		dcfg.setReuseAddress(true);
		try {
			acceptor.bind(new InetSocketAddress(udpPort));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

}
